<?php

declare(strict_types=1);

namespace app\admin\controller;

use app\utils\ResData;
use app\admin\model\MenuModel;
use app\admin\model\RoleModel;


/**
 * 角色控制器
 */
class Role
{
    // 使用检查登录、检查权限中间件
    protected $middleware = ['checklogin', 'checkpower'];

    /**
     * 角色列表
     */
    public function list()
    {
        $list = RoleModel::select();
        return view('role/index', ['roles' => $list]);
    }

    /**
     * 显示添加角色视图页面
     */
    public function add()
    {
        $list = MenuModel::where('status', 1)->field('id,pid,title')->select()->toArray();
        // 自定义索引
        $tem1 = $this->cates($list, 'id');
        // 数组转树
        $tem2 = $this->getTree($tem1);

        // // 合并三级以下菜单为平行二级菜单
        // $results = [];
        // foreach ($tem2 as $value) {
        //     // 改造children
        //     $value['children'] = isset($value['children']) ? $this->formatMenus($value['children']) : false;
        //     $results[] = $value;
        // }

        // 返回添加视图
        // return view('role/add', ['menus' => json_encode($results, JSON_UNESCAPED_UNICODE)]);
        return view('role/add', ['menus' => json_encode($tem2, JSON_UNESCAPED_UNICODE)]);
    }


    /**
     *  提交保存角色数据
     */
    public function save()
    {
        $name = trim(input('post.name', ''));
        $powers = input('post.powers', []);
        if (empty($name)) {
            return json(ResData::res(400, '角色名称不能为空'));
        }
        if (empty($powers)) {
            return json(ResData::res(400, '角色权限不能为空'));
        }


        // $menuIds = [];
        // foreach ($powers as $value) {
        //     array_push($menuIds, (int)$value['id']);
        //     if (isset($value['children'])) {
        //         foreach ($value['children'] as $v) {

        //             array_push($menuIds, (int)$v['id']);

        //             if (isset($v['children'])) {
        //                 foreach ($v['children'] as $v2) {
        //                     array_push($menuIds, (int)$v2['id']);
        //                 }
        //             }
        //         }
        //     }
        // }


        // 递归获取菜单id
        $menuIds = $this->getMenuIds($powers);

        $item = RoleModel::where('name', $name)->findOrEmpty();
        if (!$item->isEmpty()) {
            return json(ResData::res(400, '角色已存在'));
        }

        $role = new RoleModel();
        $res = $role->save(['name' => $name, 'powers' => json_encode($menuIds)]);

        if (!$res) {
            return json(ResData::res(500, '添加失败'));
        }
        return json(ResData::res(200, '添加成功'));
    }



    /**
     * 编辑角色
     */
    public function edit()
    {
        // put提交编辑数据
        if (request()->isPut()) {
            $id = (int)input('id', 0);
            $name = trim(input('name', ''));
            $powers = input('powers', []);
            if (empty($name)) {
                return json(ResData::res(400, '角色名称不能为空'));
            }
            if (empty($powers)) {
                return json(ResData::res(400, '角色权限不能为空'));
            }
            $role = RoleModel::where('id', $id)->findOrEmpty();
            if ($role->isEmpty()) {
                return json(ResData::res(400, '角色不存在'));
            }

            // 递归获取菜单id
            $menuIds = $this->getMenuIds($powers);

            $role->name = $name;
            $role->powers = json_encode($menuIds);
            $res = $role->save();

            if (!$res) {
                return json(ResData::res(500, '操作失败'));
            }
            return json(ResData::res(200, '操作成功'));
        }


        // get请求显示页面

        // 获取当前角色信息
        $id = input('id', 0);
        $role = RoleModel::where('id', $id)->findOrEmpty();
        if ($role->isEmpty()) {
            return json(ResData::res(404, '角色不存在'), 404);
        }
        // 当前角色权限(菜单ids)
        $powers = json_decode($role->powers);
        unset($role->powers);
        // dump($powers);

        // 查询使用启用状态的菜单
        $list = MenuModel::where('status', 1)->field('id,pid,title')->select()->toArray();
        // 自定义索引
        $tem1 = $this->cates($list, 'id');
        // 数组转树
        $tem2 = $this->getTree($tem1);

        // // 合并三级以下菜单为二级
        // $menus = [];
        // foreach ($tem2 as $value) {
        //     // 改造children
        //     $value['children'] = isset($value['children']) ? $this->formatMenus($value['children']) : false;
        //     $menus[] = $value;
        // }

        // // 有权限的菜单添加checked属性
        // foreach ($tem2 as &$value) {
        //     if (isset($value['children'])) {
        //         foreach ($value['children'] as &$v) {
        //             if (in_array($v['id'], $powers)) {
        //                 // echo $v['id'] . '在';
        //                 $v['checked'] = true;
        //             }
        //         }
        //     }
        // }

        $this->setChecked($tem2, $powers);

        // dump($tem2);
        // die();

        return view('role/edit', ['role' => $role, 'menus' => json_encode($tem2, JSON_UNESCAPED_UNICODE)]);
    }


    /**
     * 删除角色
     */
    public function del()
    {
        $id = input('id', 0);
        $res = RoleModel::destroy($id);
        if (!$res) {
            return json(ResData::res(500, '操作失败'));
        }
        return json(ResData::res(200, '操作成功'));
    }



    /**
     * 自定义数组索引
     * @param array $lists
     * @param string $index
     * @return array|null
     */
    private function cates(array $lists, string $index): array
    {
        if (!$lists) {
            return $lists;
        }

        $result = [];
        foreach ($lists as $key => $value) {
            $result[$value[$index]] = $value;
        }
        return $result;
    }

    /**
     * 数组转树
     * @param array $items
     * @return array
     */
    private function getTree(array $items): array
    {
        $tree = [];

        foreach ($items as $item) {
            // 判断成员pid是否存在
            if (isset($items[$item['pid']])) {
                // pid不为空时添加children成员，
                $items[$item['pid']]['children'][] = &$items[$item['id']];
            } else {
                // 没有父id直接放入tree
                $tree[] = &$items[$item['id']];
            }
        }
        return $tree;
    }


    /**
     * 合并三级子菜单函数
     * @param array $items
     * @param array $res
     * @return array
     */
    private function formatMenus(array $items, array &$res = []): array
    {
        foreach ($items as $item) {
            if (!isset($item['children'])) { // 没有子菜单
                $res[] = $item;
            } else {
                $tem = $item['children'];
                unset($item['children']);
                $res[] = $item;
                $this->formatMenus($tem, $res);
            }
        }
        return $res;
    }


    /**
     * 递归获取菜单id
     * @param array $items
     * @param array $ids
     * @return array
     */
    private function getMenuIds(array $items, array &$ids = []): array
    {
        foreach ($items as $item) {
            array_push($ids, (int)$item['id']);
            if (isset($item['children'])) {
                $this->getMenuIds($item['children'], $ids);
            }
        }
        return $ids;
    }


    /**
     * 编辑时递归判断菜单权限（是否选中）
     * @param array $items
     * @param array $powers
     */
    private function setChecked(array &$items, array &$powers)
    {
        foreach ($items as &$itme) {
            if (isset($itme['children'])) {
                // 有子菜单进行递归
                $this->setChecked($itme['children'], $powers);
            } else {
                // 无子菜单进行权限判断
                if (in_array($itme['id'], $powers)) {
                    $itme['checked'] = true;
                }
            }
        }
    }
}